#include "HapticElement.h"

namespace OpenNano
{
    REGISTER_OBJECT_FACTORY( HapticElement, HAPTIC_TAG );

    HapticElement::HapticElement(TiXmlElement *element):
                    ConfigElement(element), logger(log4cplus::Logger::getInstance( HAPTIC_TAG )),
                    _device_name(), _stiffness(1.0), _damp(0.5), _everything_is_good_so_far(true), _parameters()
            {
            }

    HapticElement::~HapticElement()
    {
        _parameters.clear();
    }

    void HapticElement::init()
    {
        LOG4CPLUS_INFO(logger, "Haptic element: initialized");
    }

    const std::string& HapticElement::getName() const
    {
        return _device_name;
    }

    double HapticElement::getStiffness()
    {
        return _stiffness;
    }

    double HapticElement::getDamp()
    {
        return _damp;
    }

    const HapticParametersMap& HapticElement::getParameters() const
    {
        return _parameters;
    }

    bool HapticElement::getParameter(const std::string& name, std::string &value)
    {
        bool parameter_found = false;
        HapticParametersMap::iterator it = _parameters.find (name);
        if (it != _parameters.end() )
        {
            value= it->second;
            parameter_found=true;
        }
        else
        {
            LOG4CPLUS_WARN(logger, "Parameter not found:");
            LOG4CPLUS_WARN(logger, name);
        }
        return parameter_found;
    }

    void HapticElement::attributeFound(TiXmlAttribute * attribute)
    {
        if ( attribute->NameTStr().compare(HAPTIC_NAME_ATTRIBUTE) == 0 )
        {
            _device_name=attribute->ValueStr();
        }
        else if (    attribute->NameTStr().compare(HAPTIC_STIFFNESS_ATTRIBUTE) == 0 &&
                attribute->QueryDoubleValue(&_stiffness)==TIXML_SUCCESS )
        {
            _stiffness=attribute->DoubleValue();
        }
        else if (    attribute->NameTStr().compare(HAPTIC_DAMP_ATTRIBUTE) == 0 &&
                attribute->QueryDoubleValue(&_damp)==TIXML_SUCCESS )
        {
            _damp=attribute->DoubleValue();
        }
        else
        {
            //attribute not recognized
            LOG4CPLUS_WARN(logger, "Attribute not recognized:");
            LOG4CPLUS_WARN(logger, attribute->NameTStr());

            unknownAttributeFound(attribute);
            _everything_is_good_so_far=false;
        }
    }

    void HapticElement::childElementFound(TiXmlElement * childElement)
    {
        if ( childElement->ValueStr().compare(HAPTIC_PARAM_TAG) == 0 )
        {
            TiXmlAttribute * param = childElement->FirstAttribute();
            if ( param && param->NameTStr().compare(HAPTIC_PARAM_NAME_ATTRIB) == 0 &&
                        param->Next() && param->Next()->NameTStr().compare(HAPTIC_PARAM_VALUE_ATTRIB) == 0 )
            {
                //NOTE_TO_SELF:
                //if there are two parameter element with the same name
                //in the map there will be only one entry, with the value defined
                //in the last parsed element.
                _parameters[ param->ValueStr() ] = param->Next()->ValueStr();
            }
            else
            {
                LOG4CPLUS_WARN(logger, "Name attribute of the parameter element not found/invalid");
                //parameter attribute not found/recognized
                _everything_is_good_so_far=false;
            }
        }
        else
        {
            //Element not recognized
            LOG4CPLUS_WARN(logger, "Child element not recognized:");
            LOG4CPLUS_WARN(logger, childElement->ValueStr());

            unknownElementFound(childElement);
            _everything_is_good_so_far=false;
        }
    }

    void HapticElement::textFound(const char* text)
    {
        LOG4CPLUS_WARN(logger, "Text not recognized:");
        LOG4CPLUS_WARN(logger, text);

        unknownTextFound(text);
    }

    bool HapticElement::postConfiguration()
    {
        return (!_device_name.empty()) && _everything_is_good_so_far;
    }



}
